package com.alifi.crm.dal.guess;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.HttpURLConnection;
import java.net.Socket;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.Calendar;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

import com.alibaba.common.lang.StringUtil;





/**
 * 
 * @author wenjing.huangwj
 *
 */
public class Assistant {
	
	
	
	/**
	   * 在同一名称的属性,将src中getter方法返回的值赋给tag中setter方法对应的值
	   * 注意:src中必须包括所有tag的方法.即只能多,不能少. 否则没有被包含的方法将不会被赋值
	   *     方法必须是public的．不处理其他类型的方法．
	   * @param src
	   * @param tag
	   */
	 public static void copy(Object src, Object tag) {
		    try {
		      Method[] mt = tag.getClass().getMethods();
		      for (int i = 0; i < mt.length; i++) {
		        try {
		          if (mt[i].getName().startsWith("set")) {
		            String filed = mt[i].getName().substring(3);
		            Object param = src.getClass().getMethod("get" + filed,
		                null).invoke(src, null);
		            if (param == null) {
		              continue;
		            }
		            mt[i].invoke(tag, new Object[] {param});
		          }
		        }
		        catch (NoSuchMethodException ex) {

		        }
		      }
		    }
		    catch (SecurityException ex) {
		      ex.printStackTrace();
		    }

		    catch (InvocationTargetException ex) {
		      ex.printStackTrace();
		    }
		    catch (IllegalArgumentException ex) {
		      ex.printStackTrace();
		    }
		    catch (IllegalAccessException ex) {
		      ex.printStackTrace();
		    }
		  }

    
	    /**
      *将输入的参数首字母大写，并在之前加set返回.
      * @param param
      * @return String
      * @throws java.lang.Exception
      */
   public static String getSetMethod(String param) {
       if (StringUtil.isBlank(param)) {
             return null;
       }
       if(param.length()==1){
           return "set" +param.toUpperCase();
       }
       return "set" +param.substring(0,1).toUpperCase()+param.substring(1,param.length());
    }
   
   /**
      *将输入的参数首字母大写，并在之前加set返回.
      * @param param
      * @return String
      * @throws java.lang.Exception
      */
   public static String getGetMethod(String param) {
       if (StringUtil.isBlank(param)) {
         return null;
       }
       if(param.length()==1){
            return "get" +param.toUpperCase();
       }
       return "get" +param.substring(0,1).toUpperCase()+param.substring(1,param.length());
       
    }

	  
	  


	  
	  /**
		 * 调用 obj对象的 methodName方法.此方法必须有入参.
		 * @param obj
		 * @param methodName
		 * @param params
		 * @throws Exception
		 */
		public static void invokeSetMethod(Object obj,String paramName,Object param,Class paramType) {
			Method m = null;
			try{
				m = obj.getClass().getMethod(getSetMethod(paramName),new Class[]{paramType});
				m.invoke(obj, new Object[]{param});
			}
			catch (NoSuchMethodException e) {
				
			} 
			catch (IllegalArgumentException e) {
			    throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e);
            }	
		}
		
		/**
		 * 
		 * @param obj
		 * @param methodName
		 * @param param
		 * @param paramType
		 */
	      public static void invokeMethod(Object obj,String methodName,Object param,Class paramType) {
	            Method m = null;
	            try{
	                m = obj.getClass().getMethod(methodName,new Class[]{paramType});
	                m.invoke(obj, new Object[]{param});
	            }
	            catch (NoSuchMethodException e) {
	                
	            } catch (IllegalArgumentException e) {
	                throw new RuntimeException(e);
                } catch (IllegalAccessException e) {
                    throw new RuntimeException(e);
                } catch (InvocationTargetException e) {
                    throw new RuntimeException(e);
                }
	       }
		
		
		  /**
		 * 调用 obj对象的 getmethodName方法.
		 * @param obj
		 * @param methodName
		 * @param params
		 * @throws Exception
		 */
		public static Object invokeGetMethod(Object obj,String paramName) {
			Method m = null;
			try{
				m = obj.getClass().getMethod(getGetMethod(paramName),null);
				return m.invoke(obj, null);
			}
			catch (NoSuchMethodException e) {
				
			} catch (IllegalArgumentException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e);
            }
			return null;
			}
		
		/**
		 * 判断类是否存在
		 * @param className
		 * @return boolean
		 */
		public static boolean isExist(String className){
			try {
				Class.forName(className);
				return true;
			} catch (ClassNotFoundException e) {
				return false;
			}
		}
	  
	  /**
	   * 将符合yyyy-MM-DD HH:mm:SS 格式或其子格式的字符串转换为对应的时间对象
	   * @param str
	   * @param cls 定义返回的类型.
	   * @return java.util.Date 或其子类
	   */
	  public static java.util.Date createDate(String str,Class cls) throws Exception {
		  if(str==null||str.length()<4||str.length()>19) throw new Exception("时间格式不正确");
		  str = str.trim();
		  Calendar c = Calendar.getInstance();
		  int year = c.get(Calendar.YEAR);
		  int month = 1;
		  int date = 1;
		  int hour = 0;
		  int minute = 0;
		  int second = 0;
		  switch(str.length()){
		  case 4:{
			  year = Integer.parseInt(str.substring(0, 4));
			  break;
		  }
		  case 7:{
			  year = Integer.parseInt(str.substring(0, 4));
			  month = Integer.parseInt(str.substring(5, 7)) - 1;
			  break;
		  }
		  case 10:{
			  year = Integer.parseInt(str.substring(0, 4));
			  month = Integer.parseInt(str.substring(5, 7)) - 1;
			  date = Integer.parseInt(str.substring(8,10));
			  break;
		  }
		  case 13:{
			  year = Integer.parseInt(str.substring(0, 4));
			  month = Integer.parseInt(str.substring(5, 7)) - 1;
			  date = Integer.parseInt(str.substring(8,10));
			  hour = Integer.parseInt(str.substring(11,13));
			  break;
		  }
		  case 16:{
			  year = Integer.parseInt(str.substring(0, 4));
			  month = Integer.parseInt(str.substring(5, 7)) - 1;
			  date = Integer.parseInt(str.substring(8,10));
			  hour = Integer.parseInt(str.substring(11,13));
			  minute = Integer.parseInt(str.substring(14,16));
			  break;
		  }
		  case 19:{
			  year = Integer.parseInt(str.substring(0, 4));
			  month = Integer.parseInt(str.substring(5, 7)) - 1;
			  date = Integer.parseInt(str.substring(8,10));
			  hour = Integer.parseInt(str.substring(11,13));
			  minute = Integer.parseInt(str.substring(14,16));
			  second = Integer.parseInt(str.substring(17,19));
			  break;
		  }
		  default: throw new Exception("***时间格式不正缺***");
		  }
	    c.set(year, month, date,hour,minute,second);
	    
	    if(cls.isAssignableFrom(java.sql.Date.class))
	    return new java.sql.Date(c.getTimeInMillis());
	    else if(cls.isAssignableFrom(java.sql.Timestamp.class))
	    return new java.sql.Timestamp(c.getTimeInMillis());
	     return new java.util.Date(c.getTimeInMillis());
	  }
	  
	  /**
	   * 判断输入的参数是否是基本类型
	   * @param c
	   * @return int
	   * 		 1: Integer
	   * 		 2: Float
	   * 	     3: Double
	   *         0: String
	   */
	  public static int isBasicType(Class c){
	    if((c.isAssignableFrom(int.class))||(c.isAssignableFrom(java.lang.Integer.class))){
	       return 1;
	    }
	    if(c.isAssignableFrom(float.class)||(c.isAssignableFrom(java.lang.Float.class))){
	      return 2;
	    }
	    if(c.isAssignableFrom(double.class)||(c.isAssignableFrom(java.lang.Double.class))){
	      return 3;
	    }
	    if(c.isAssignableFrom(long.class)||(c.isAssignableFrom(java.lang.Long.class))){
		      return 4;
		    }
	    return 0;
	  }
	  
	  
	  /**
	   * 将value转还为c类型
	   * @param c
	   * @param value
	   * @return Object
	   */
	  public static Object castValue(Class c,Object value){
		  int it = isBasicType(c);
		  switch(it){
          case 0: return value; //f[i].getType()类型.
          case 1: return new Integer(value.toString());
          case 2: return new Float(value.toString());
          case 3: return new Double(value.toString());
          case 4: return new Long(value.toString());
          default: return c.cast(value);
        }
	  
	  }
	  

	  public static String sendGetRequest(String cookie,String urlStr,Properties p,Properties outP,boolean isPrint) throws Exception{
			//System.out.println("开始向 "+urlStr+" 发送GET请求");
			URL url = new URL(urlStr);
			HttpURLConnection conn = (HttpURLConnection)url.openConnection();
	
			conn.setDoInput(true);
			conn.setDoOutput(true);
			conn.setUseCaches(false);
			conn.setRequestMethod("GET");
			if(cookie!=null) conn.setRequestProperty("Cookie",cookie);
//			conn.setRequestProperty("Connection", "Keep-Alive");
//			conn.setRequestProperty("Cache-Control", "max-age=0");
//			conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 5.1; rv:16.0) Gecko/20100101 Firefox/16.0");
			if(p!=null){
			Enumeration enu = p.keys();
			while(enu.hasMoreElements()){
				String name = enu.nextElement()+"";
				String value = p.getProperty(name);
				conn.addRequestProperty(name, value);
			}
			}
			String str = null;
			StringBuffer sb = new StringBuffer();
			BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(),"utf-8"));
			while((str=in.readLine())!=null){
				if(isPrint){
					System.out.println(str);
				}
				sb.append(str+"\n");
				
			}
			
			
			//System.out.println("/*************头信息************/");
			Map map = conn.getHeaderFields();
			Iterator<String> it = map.keySet().iterator();
			while(it.hasNext()){
				String name = it.next();
				//System.out.println(name+":  "+map.get(name));
				if(name!=null) outP.setProperty(name, map.get(name).toString().substring(1,map.get(name).toString().length()-1));
			}
			
			
			in.close();
			conn.disconnect();
			return sb.toString();
		}
	  
	  
	  
	  /**
	   * 发送post请求
	   * @param sessionId
	   * @param urlStr
	   * @param isPrint
	   * @param content
	   * @return 返回http响应
	   * @throws Exception
	   */
	  public static String sendPostRequest(String sessionId,String urlStr,Properties p, boolean isPrint,String content) throws Exception{
//			System.out.println("开始向 "+urlStr+" 发送POST请求");
			URL url = new URL(urlStr);
			HttpURLConnection conn = (HttpURLConnection)url.openConnection();
			conn.setDoInput(true);
			conn.setDoOutput(true);
			conn.setUseCaches(false);
			conn.setRequestMethod("POST");
			if(sessionId!=null) conn.setRequestProperty("Cookie",sessionId);
//			conn.setRequestProperty("Connection", "Keep-Alive");
//			conn.setRequestProperty("Cache-Control", "no-cache");
//			conn.setRequestProperty("User-Agent", "Mozilla/6.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
			if(p!=null){
				Enumeration enu = p.keys();
				while(enu.hasMoreElements()){
					String name = enu.nextElement()+"";
					String value = p.getProperty(name);
					conn.setRequestProperty(name, value);
				}
			}
			
			BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(),"utf-8"));
			writer.write(content);
			writer.flush();
			
			String setCookie = conn.getHeaderField("Set-Cookie");
			if(setCookie!=null&&p!=null){
				p.put("setCookie", setCookie);
			}
			
			StringBuffer sb = new StringBuffer(); 
			String str = null;
			BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(),"utf-8"));
			while((str=in.readLine())!=null){
				if(isPrint){
					System.out.println(str);
				}
					sb.append(str+"\r\n");
				}
			in.close();
			writer.close();
			conn.disconnect();
			return sb.toString();
		}
	  
	  /**
	   * 读取文件
	   * @param file
	   * @return
	   * @throws IOException
	   */
	  public  static String createContent(String file) throws IOException{
		  	File f = new File(file);
			FileInputStream in = new FileInputStream(f);
			byte[] byt = new byte[Integer.parseInt(f.length()+"")];
			
			in.read(byt);
//			for(int i=0;i<byt.length;i++){
//				System.out.print(" "+byt[i]);
//				if(i%15==0) System.out.println("");
//			
//			}
			in.close();
			return new String(byt,"utf-8");

	  }

		/**
		 * 发送http请求
		 * @param ipAddress    ip地址
		 * @param port		   端口号	
		 * @param content      发送的内容
		 * @throws UnknownHostException
		 * @throws IOException
		 * @return response
		 */
	  public static Properties sendHttpRequest(String ipAddress,int port,String content) throws UnknownHostException, IOException{
		//System.out.println("向"+ipAddress+" "+port+"端口发送请求信息如下\n"+content);
		  	Properties p = new Properties();
		  	Socket socket = new Socket(ipAddress,port);
			BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),"utf-8"));
			out.write(content);
			out.flush();
			
			InputStream itm = socket.getInputStream();
			BufferedReader in =new BufferedReader(new InputStreamReader(itm,"utf-8"));
			String str = null;
			
			StringBuffer sb = new StringBuffer();
			int length = 0;
		
			boolean state = false;
			boolean isSupportType = true;  //只支持text/html类型
			
			//System.out.println("发出\n"+content);
			while((str=in.readLine())!=null){
				
				sb.append(str+"\r\n");
				if(str.indexOf("Content-Length")!=-1){
					
					String[] strs = str.trim().split(" ");
					if(strs[strs.length-1].equalsIgnoreCase("")){
						length = 0;
					}
					else{
						length = Integer.parseInt(strs[strs.length-1].trim());
					}
				}
				
				if(str.indexOf("Content-Type")!=-1){
					String[] types = str.trim().split(" ");
					
					if(types.length>1){
						p.setProperty("Content-Type", types[1]);
						String[] subtypes = types[1].split(";");
						if(subtypes[0].indexOf("text/html")==-1){
							isSupportType = false;
						}
					}
				}
				
				else if(str.equalsIgnoreCase("")||str.equalsIgnoreCase("\r\n")){
					//System.out.println("头信息结束");
					break;
				}
				else if(str.indexOf("HTTP")!=-1){
					p.setProperty("vision", str);
				}
				else{
					String strs[] = str.split(": ");
					if(strs.length>1){
						p.setProperty(strs[0], strs[1]);
					}
				}
			}
			if(isSupportType){
				
			if(length!=0){
				char[] byt = new char[length];
				
					char[] tmp = new char[4096];
					int s = (length-1)/4096+1;
					
					for(int i=0;i<s;i++){
						int a = in.read(tmp);
						int index = i*4096;
						copy(byt, tmp, a, i);
					}
				
				sb.append((new String(byt)));
				}
			}
			else{
				sb.append("不支持返回的类型");
			}
			if(out!=null) out.close();
			if(in!=null) in.close();
			if(socket!=null) socket.close();
			
			p.setProperty("response", sb.toString());
			
		//	System.out.println("响应\n"+sb.toString()+"\n");
			return p;
		}
	  
	  /**
	   * 解析http响应
	   * @param response   http响应
	   * @param values     0:  sessionId
	   * 				   1:  location
	   * @return           http状态码
	   * @throws IOException
	   */
	  public static int parseHttpState(String response,String[] values) throws IOException{
		  if(values.length<2) return -1;
		  

		  
		  BufferedReader in = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(response.getBytes("utf-8")),"utf-8"));
		  String str = in.readLine();
		  
		  String tmp = null;
		  while((tmp=in.readLine())!=null){
			  if(tmp.equalsIgnoreCase("")){
				  break;
			  }
			  if(tmp.indexOf("JSESSIONID")!=-1){
				  int start = tmp.indexOf("JSESSIONID");
				  int end = (tmp.indexOf(";")==-1?tmp.length():tmp.indexOf(";"));
				  values[0] = tmp.substring(start,end);
			  }
			  
			  else if(tmp.indexOf("IPCZQX03a36c6c0a")!=-1){
				  int start = tmp.indexOf("IPCZQX03a36c6c0a");
				  int end = (tmp.indexOf(";")==-1?tmp.length():tmp.indexOf(";"));
				  values[0] = tmp.substring(start,end);
			  }
			  
			  
			  
			  else if(tmp.indexOf("Location")!=-1){
				 String[] t = tmp.split(" ");
				 values [1]= t[1];
			  }
			  
			  
		  }
		  
		  if(in!=null) in.close();
		  String[] a = str.split(" ");
		  if(a.length<2) return -1;
		  else return Integer.parseInt(a[1]);
	  }
	  
	  /**
	   * 将two的twoLength个字节复制到all中,从all的第i个位置开始.包括i.
	   * @param all
	   * @param two
	   * @param twoLength
	   * @param i
	   * @return
	   */
	  public static char[] copy(char[] all,char[] two,int twoLength,int i){	
			for(int j=0;j<twoLength;j++){
				all[i] = two[j];
				i++;
			}
			return all;
			
	  }
	  
}


